package com.lz.gmall.cart.biz.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.lz.gamll.feign.product.SkuDetailFeignClient;
import com.lz.gmall.cart.biz.AddCartBizService;
import com.lz.gmall.cart.entity.CartItem;
import com.lz.gmall.cart.vo.AddCartVo;
import com.lz.gmall.cart.vo.UserAuthInfoVo;
import com.lz.gmall.common.execption.GmallException;
import com.lz.gmall.common.result.ResultCodeEnum;
import com.lz.gmall.common.utils.UserAuthUtil;
import com.lz.gmall.constant.GmallConstant;
import com.lz.gmall.product.entity.SkuInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class AddCartBizServiceImpl implements AddCartBizService {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private SkuDetailFeignClient skuDetailFeignClient;

    private static final int SKU_NUM = 10;

    @Override
    public AddCartVo addCart(Long skuId, Integer skuNum) {


        //获取购物车的redis中的key
        String cartKey = getCartKey();

        //将skuId转换成string
        String skuIdStr = String.valueOf(skuId);

        //获取商品的详细信息，进行远程调用service-product接口
        SkuInfo skuInfo = skuDetailFeignClient.getSkuInfoAndImageById(skuId).getData();

        Boolean hasKey = redisTemplate.opsForHash().hasKey(cartKey, skuIdStr);
        if (hasKey){
            //购物车中有该商品，进行累加啊操作
            String cartItemJson = redisTemplate.opsForHash().get(cartKey, skuIdStr).toString();
            CartItem cartItem = JSON.parseObject(cartItemJson, CartItem.class);

            cartItem.setSkuNum(Math.min(cartItem.getSkuNum() + skuNum, SKU_NUM));

            //修改完数量存入redis
            redisTemplate.opsForHash().put(cartKey,skuIdStr,JSON.toJSONString(cartItem));
        }else {

            List<Object> values = redisTemplate.opsForHash().values(cartKey);
            if (values.size()>=3){
                throw new GmallException(ResultCodeEnum.CART_NUM_ERROR);
            }

            //购物车没有商品，进行添加操作
            CartItem cartItem = new CartItem();
            cartItem.setId(skuId);
            cartItem.setSkuId(skuId);
            cartItem.setCartPrice(skuInfo.getPrice());
            cartItem.setSkuPrice(skuInfo.getPrice());
            if (skuNum>SKU_NUM){
                cartItem.setSkuNum(SKU_NUM);
            }
            cartItem.setSkuNum(skuNum);
            cartItem.setImgUrl(skuInfo.getSkuDefaultImg());
            cartItem.setSkuName(skuInfo.getSkuName());
            cartItem.setIsChecked(1);
            cartItem.setCreateTime(new Date());
            cartItem.setUpdateTime(new Date());
            //添加到redis
            redisTemplate.opsForHash().put(cartKey,skuIdStr,JSON.toJSONString(cartItem));
        }

        AddCartVo addCartVo = new AddCartVo();
        addCartVo.setSkuInfo(skuInfo);
        addCartVo.setSkuNum(skuNum);

        //给临时数据库设置过期时间
        UserAuthInfoVo userAuthInfo = UserAuthUtil.getUserAuthInfo();
        assert userAuthInfo != null;
        String userId = userAuthInfo.getUserId();
        if(StringUtils.isEmpty(userId)){
            //userId为空,说明操作的是临时数据库
            Long expire = redisTemplate.getExpire(cartKey);
            if (expire < 0){
                redisTemplate.expire(cartKey,30, TimeUnit.DAYS);
            }
        }

        return addCartVo;
    }

    /**
     * 从redis中获取到用户购物车选中商品
     * 生成订单用户必须登录，所以获取到的就是用户购物车
     * @return
     */
    @Override
    public List<CartItem> getCheckedCartItem() {
        //用户购物车
        String cartKey = getCartKey();
        List<Object> cartItemObjList = redisTemplate.opsForHash().values(cartKey);

        List<CartItem> cartItemList = cartItemObjList.stream().map(obj -> {
            String cartItemJson = obj.toString();
            return JSON.parseObject(cartItemJson, CartItem.class);
        }).filter(cartItem -> {
            return cartItem.getIsChecked() == 1;
        }).collect(Collectors.toList());

        return cartItemList;
    }

    /**
     * 远程调用，生成订单之后，删除购物车中选中生成订单的商品
     * 生成订单，必须是用户登录
     * @return
     */
    @Override
    public void deleteCheckedCartItem() {
        String cartKey = getCartKey();
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);

//        List<CartItem> cartItemList = objectList.stream().map(obj -> {
//            String cartItemJson = obj.toString();
//            return JSON.parseObject(cartItemJson, CartItem.class);
//        }).filter(cartItem -> cartItem.getIsChecked() == 1).collect(Collectors.toList());
//
//        List<Long> skuIdList = cartItemList.stream().map(cartItem -> cartItem.getSkuId()).collect(Collectors.toList());
//        redisTemplate.opsForHash().delete(cartKey,skuIdList);

        objectList.forEach(obj->{
            String cartItemJson = obj.toString();
            CartItem cartItem = JSON.parseObject(cartItemJson, CartItem.class);
            if (cartItem.getIsChecked()==1){
                redisTemplate.opsForHash().delete(cartKey,String.valueOf(cartItem.getSkuId()));
            }
        });

    }

    private String getCartKey() {
        //获取请求头中的用户id和临时id
        UserAuthInfoVo userAuthInfo = UserAuthUtil.getUserAuthInfo();
        assert userAuthInfo != null;
        String userId = userAuthInfo.getUserId();
        String userTempId = userAuthInfo.getUserTempId();

        if (!StringUtils.isEmpty(userId)){
            //说明用户已经登录了
            return GmallConstant.REDIS_USER_CART_KEY + userId;
        }else {
            //说明用户没有登录
            return GmallConstant.REDIS_USER_CART_KEY+userTempId;
        }
    }
}
